微信开发之微信支付相关算法实现

2024-09-01 23:08

本文主要是介绍微信开发之微信支付相关算法实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

微信开发中,涉及到微信支付流程较为繁琐。其中以微信红包为例,参考官方文档:https://pay.weixin.qq.com/wiki/doc/api/tools/cash_coupon.php?chapter=13_4&index=3。
调用微信支付链接中,有以下三个字段,需要依据相关算法要求生成。分别是签名(sign),订单号(mch_billno)以及随机字符串(nonce_str)。下面用Java依据算法流程,实现了微信支付工具类,用于生成上述三个字段。
代码如下,已经过测试:


/*** Created by Song on 2016/11/8.* mail: 1147649695@qq.com* 微信支付相关工具类*/
public class PayWxUtil {//上一次订单请求日期private static Date preDay = new Date();//当前订单日期private static Date curDay = new Date();//用于记录已产生的订单号private static Set<Long> numPoul = new HashSet<Long>();/*** 获得签名* @param params 待编码参数,参数值为空不传入* @param key key设置路径:微信商户平台(pay.weixin.qq.com)-->账户设置-->API安全-->密钥设置* @return*/public static String getSign(Map<String,String> params,String key){List<String> list = new ArrayList<String>(params.keySet());Collections.sort(list,new DictionaryCompare());StringBuffer sb = new StringBuffer();for(String keyVal:list){sb.append(keyVal+"="+params.get(keyVal)+"&");}sb.append("key="+key);return DigestUtils.md5Hex(sb.toString()).toUpperCase();}/*** 获得随机字符串* @return*/public static String getNonceStr(){Random random = new Random();long val = random.nextLong();String res = DigestUtils.md5Hex(val+"yzx").toUpperCase();if(32<res.length()) return res.substring(0,32);else return res;}/*** 获取订单号* 商户订单号(每个订单号必须唯一)* 组成:mch_id+yyyymmdd+10位一天内不能重复的数字。* @param mchId* @return*/public static String getMchBillno(String mchId){Random random = new Random();long val = random.nextLong()%10000000000L;//获得0-9999999999内的数字curDay = new Date();//隔天清空if(curDay.after(preDay)) numPoul.clear();while(numPoul.contains(val)){val = random.nextLong()%10000000000L;}numPoul.add(val);preDay = curDay;//按要求,日期格式化输出DateFormat df = new SimpleDateFormat("yyyymmdd");return mchId+df.format(curDay)+format(val+"",10);}/*** 将字符串str按长度在前面添0补齐* @param str* @param length* @return*/private static String format(String str,int length){String pre = "0000000000";int len = str.length();if(10<=len) return str.substring(0,10);else return pre.substring(0,10-len).concat(str);}}/*** 按字典序排序*/
class DictionaryCompare implements Comparator<String>{public int compare(String o1, String o2) {return o1.compareTo(o2);}
}

其中,签名(sign)的算法流程参考官方说明签名算法其具体实现过程摘录如下:
(1)设所有发送或者接收到的数据为集合M,将集合M内非空参数值的参数按照参数名ASCII码从小到大排序(字典序),使用URL键值对的格式(即key1=value1&key2=value2…)拼接成字符串stringA
(2)在stringA最后拼接上key得到stringSignTemp字符串,并对stringSignTemp进行MD5运算,再将得到的字符串所有字符转换为大写,得到sign值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位,并按规则组合,得到订单号并返回。
部分细节方面,可能还有疏漏,若有问题,发现将及时改正更新,也欢迎大家提出存在的问题和看法。

这篇关于微信开发之微信支付相关算法实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1128304

相关文章

Python实现终端清屏的几种方式详解

《Python实现终端清屏的几种方式详解》在使用Python进行终端交互式编程时,我们经常需要清空当前终端屏幕的内容,本文为大家整理了几种常见的实现方法,有需要的小伙伴可以参考下... 目录方法一:使用 `os` 模块调用系统命令方法二:使用 `subprocess` 模块执行命令方法三:打印多个换行符模拟

SpringBoot+EasyPOI轻松实现Excel和Word导出PDF

《SpringBoot+EasyPOI轻松实现Excel和Word导出PDF》在企业级开发中,将Excel和Word文档导出为PDF是常见需求,本文将结合​​EasyPOI和​​Aspose系列工具实... 目录一、环境准备与依赖配置1.1 方案选型1.2 依赖配置(商业库方案)二、Excel 导出 PDF

Python实现MQTT通信的示例代码

《Python实现MQTT通信的示例代码》本文主要介绍了Python实现MQTT通信的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一... 目录1. 安装paho-mqtt库‌2. 搭建MQTT代理服务器(Broker)‌‌3. pytho

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

使用zip4j实现Java中的ZIP文件加密压缩的操作方法

《使用zip4j实现Java中的ZIP文件加密压缩的操作方法》本文介绍如何通过Maven集成zip4j1.3.2库创建带密码保护的ZIP文件,涵盖依赖配置、代码示例及加密原理,确保数据安全性,感兴趣的... 目录1. zip4j库介绍和版本1.1 zip4j库概述1.2 zip4j的版本演变1.3 zip4

python生成随机唯一id的几种实现方法

《python生成随机唯一id的几种实现方法》在Python中生成随机唯一ID有多种方法,根据不同的需求场景可以选择最适合的方案,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习... 目录方法 1:使用 UUID 模块(推荐)方法 2:使用 Secrets 模块(安全敏感场景)方法

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

Linux下删除乱码文件和目录的实现方式

《Linux下删除乱码文件和目录的实现方式》:本文主要介绍Linux下删除乱码文件和目录的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux下删除乱码文件和目录方法1方法2总结Linux下删除乱码文件和目录方法1使用ls -i命令找到文件或目录