diff --git a/package.json b/package.json index 17a3841..181fc98 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nt-addon-pay", - "version": "0.5.5", + "version": "0.5.6", "description": "The pay addon for notadd application", "scripts": { "start": "ts-node -r tsconfig-paths/register starter/main.ts", diff --git a/src/modules/wechat/interfaces/order.interface.ts b/src/modules/wechat/interfaces/order.interface.ts index 99ad790..f8f82df 100644 --- a/src/modules/wechat/interfaces/order.interface.ts +++ b/src/modules/wechat/interfaces/order.interface.ts @@ -21,9 +21,17 @@ interface WeChatBaseOrderRequestParam { spbill_create_ip: string; /** 订单优惠标记 */ goods_tag?: string; - /** 交易起始时间 */ + /** + * 交易起始时间 + * + * 格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010 + */ time_start?: string; - /** 交易结束时间,建议:最短失效时间间隔大于1分钟 */ + /** + * 交易结束时间,建议:最短失效时间间隔大于1分钟 + * + * 格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010 + */ time_expire?: string; /** 场景信息 */ scene_info?: string; diff --git a/src/modules/wechat/interfaces/refund.interface.ts b/src/modules/wechat/interfaces/refund.interface.ts index f667636..91f0409 100644 --- a/src/modules/wechat/interfaces/refund.interface.ts +++ b/src/modules/wechat/interfaces/refund.interface.ts @@ -2,7 +2,7 @@ import { WeChatBaseResponse } from './base.interface'; /** 微信支付申请退款接口基础请求参数 */ export interface WeChatBaseRefundReqParam { - /** 微信订单号,优先使用 */ + /** 微信订单号,优先级高于商户订单号 */ transaction_id?: string; /** 商户订单号 */ out_trade_no?: string; diff --git a/src/modules/wechat/utils/request.util.ts b/src/modules/wechat/utils/request.util.ts index 816ba0d..db5d974 100644 --- a/src/modules/wechat/utils/request.util.ts +++ b/src/modules/wechat/utils/request.util.ts @@ -62,4 +62,58 @@ export class WeChatRequestUtil { throw new Error('微信支付请求接口时出现网络异常:' + error.toString()); } } + + /** + * 检查请求参数单号正确性 + * + * @param params 请求参数 + */ + checkParamNo(params: any) { + for (const no of ['out_trade_no', 'out_refund_no', 'mch_billno', 'partner_trade_no']) { + if (Object.keys(params).includes(no)) { + switch (no) { + case 'out_trade_no': + this.regexpTest(params, 'out_trade_no', 32, 'special'); + break; + case 'out_refund_no': + this.regexpTest(params, 'out_refund_no', 64, 'special'); + break; + case 'mch_billno': + this.regexpTest(params, 'mch_billno', 28, 'normal'); + break; + case 'partner_trade_no': + this.regexpTest(params, 'partner_trade_no', 32, 'normal'); + break; + } + } + } + } + + /** + * 参数正则匹配校验 + * + * @param params 参数对象 + * @param propertyName 参数属性名 + * @param maxLength 参数值最大长度 + * @param regexpType 匹配类型 + */ + regexpTest(params: any, propertyName: string, maxLength: number, regexpType: 'normal' | 'special') { + if (params[propertyName].length > maxLength) { + throw new Error(`参数 ${propertyName} 长度不能大于 ${maxLength} 个字符`); + } + + const normalRegexp = new RegExp(/^[A-Za-z0-9]+$/, 'g'); + const specialRegexp = new RegExp(/^[A-Za-z0-9_\-|\*@]+$/, 'g'); + if (regexpType === 'normal') { + if (!normalRegexp.test(params[propertyName])) { + throw new Error(`参数 ${propertyName} 只能是字母或者数字`); + } + } + + if (regexpType === 'special') { + if (!specialRegexp.test(params[propertyName])) { + throw new Error(`参数 ${propertyName} 只能是数字、大小写字母或_-|*@`); + } + } + } } \ No newline at end of file diff --git a/src/shared/utils/random.util.ts b/src/shared/utils/random.util.ts index 0c59619..73312f4 100644 --- a/src/shared/utils/random.util.ts +++ b/src/shared/utils/random.util.ts @@ -10,6 +10,6 @@ export class RandomUtil { * 生成32位随机字符串 */ genRandomStr() { - return chance().string({ length: 30, pool: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' }); + return chance().string({ length: 32, pool: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' }); } } \ No newline at end of file