微信交易单号尾号算法如何实现?分析微信单号尾数规律

9158APP 0

微信交易单号尾号算法如何实现?分析微信单号尾数规律

如今,大多数人通过微信进行支付交易。通过微信完成交易后,我们将收到一个微信交易号。这个交易号可以显示汇款的内容和金额,并可以及时验证。对此,有谁知道微信交易号的尾号算法是如何实现的吗?接下来小编就为大家分析一下微信交易号的尾号规则。

在微信开发中,微信支付流程相对繁琐。以微信红包为例,请参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4index=3。

在调用微信支付的链接中,有以下三个字段,需要根据相关算法要求生成。它们是签名(sign)、订单号(mch_billno)和随机字符串(nonce_str)。下面根据算法流程使用Java实现微信支付工具类,用于生成上述三个字段。

代码如下,已测试

/**

* 由宋于2016年11月8日创作。

* 邮箱:1147649695@qq.com

* 微信支付相关工具

*/

公共类PayWxUtil {

//最后订单请求日期

私有静态日期preDay=new Date();

//当前订单日期

私有静态日期curDay=new Date();

//用于记录生成的订单号

私有静态Set numPoul=new HashSet();

/**

* 获取签名

* @param params 要编码的参数,如果参数值为空则不会传入

* @参数键

密钥设置路径:微信商户平台(pay.weixin.qq.com)--账户设置--API安全--密钥设置

* @返回

*/

公共静态字符串getSign(地图参数,字符串键){

列表列表=new ArrayList(params.keySet());

Collections.sort(列表,new DictionaryCompare());

StringBuffer sb=new StringBuffer();

for(字符串keyVal:列表){

sb.append(keyVal+'='+params.get(keyVal)+'');

}

sb.append('key='+key);

返回DigestUtils.md5Hex(sb.toString()).toUpperCase();

}

/**

* 获取随机字符串

* @返回

*/

公共静态字符串getNonceStr(){

随机随机=new Random();

long val=random.nextLong();

String res=DigestUtils.md5Hex(val+'yzx').toUpperCase();

如果(32

否则返回res;

}

/**

* 获取订单号

* 商户订单号(每个订单号必须唯一)

* 组成:mch_id+yyyymmdd+一天内不能重复的10位数字。

* @param mchId

* @返回

*/

公共静态字符串getMchBillno(字符串mchId){

随机随机=new Random();

long val=random.nextLong()%10000000000L;//获取0-9999999999内的数字

curDay=新日期();

//第二天清零

if(curDay.after(preDay)) numPoul.clear();

while(numPoul.contains(val)){

val=random.nextLong()%10000000000L;

}

numPoul.add(val);

前日=当前日;

//根据需要,日期格式输出

DateFormat df=new SimpleDateFormat('yyyymmdd');

return mchId+df.format(curDay)+format(val+'',10);

}

/**

* 根据长度在字符串str前面添加0

* @参数str

* @参数长度

* @返回

*/

私有静态字符串格式(字符串str,int长度){

字符串pre='0000000000';

int len=str.length();

if(10=len) 返回str.substring(0,10);

否则返回pre.substring(0,10-len).concat(str);

}

}

/**

* 按字典顺序排序

*/

类DictionaryCompare 实现比较器{

公共int 比较(字符串o1,字符串o2){

返回o1.compareTo(o2);

}

}

Cheng参考了官方对签名算法的描述,其具体实现过程摘录如下:

(1)假设所有发送或接收的数据是一个集合M,集合M中参数值非空的参数按照参数名的ASCII码从小到大排序(字典顺序),使用URL键值对的格式(即key1=value1key2=value2…)串联成字符串stringA

(2)在stringA末尾拼接key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,然后将得到的字符串所有字符转换为大写,得到符号值signValue。

关于订单号生成,要求订单号后10位为当天不可重复的10位。这里使用一个静态Set来存储当天生成的数字。需要注意的是,这种方式如果在服务器上重新部署项目,静态值会被清除,可能会导致错误;当一天的访问量非常高,接近上限9999999999时,获取随机值的计数时间会明显增加,会占用JVM永久区的大量内存资源被消耗。如果JVM相关参数配置不当,可能会导致PermSize溢出异常,导致系统崩溃。在这两种情况下,都建议根据数据库字段增量来获取值。当然,这种方法目前是基于该项目每日红包发送量较低的情况下,所以无需考虑上述情况。具体实现是:

(1) 生成0-9999999999类型的随机数

(2)判断当前日期curDay是否在上次请求日期preDay之后,如果是则执行(3),否则执行(4)

(3)清除随机数静态缓存numPoul

(4)判断随机数是否在静态缓存资源numPoul中。如果存在则执行(1),否则执行(5)

(5) 将随机数写入numPoul,并将preDay更新为当前日期

(6) 将随机数加0,使其成为10位,按照规则组合得到订单号并返回。

大家知道我们微信交易后获取到的微信交易订单号的尾号也是有规律的吗?那么微信交易订单号的尾号算法是如何实现的呢?以上就是小编为大家分析的微信分析交易单号尾号的规则和原理。